// ============ AI工具调度系统 - 工具函数 ============

/**
 * 稳定 JSON 序列化（缓存 key 生成）
 */
export function stableStringify(obj: any): string {
  if (obj === null || obj === undefined) return String(obj);
  if (typeof obj !== 'object') return JSON.stringify(obj);
  
  if (Array.isArray(obj)) {
    return '[' + obj.map(stableStringify).join(',') + ']';
  }
  
  const keys = Object.keys(obj).sort();
  const pairs = keys.map(key => `"${key}":${stableStringify(obj[key])}`);
  return '{' + pairs.join(',') + '}';
}

/**
 * 组合多个 AbortSignal，尽量使用原生 any；否则降级实现
 */
export function combineSignals(signals: (AbortSignal | undefined)[]): AbortSignal | undefined {
  const list = signals.filter(Boolean) as AbortSignal[];
  if (list.length === 0) return undefined;
  
  const anyFn = (AbortSignal as any).any as ((signals: AbortSignal[]) => AbortSignal) | undefined;
  if (typeof anyFn === 'function') return anyFn(list);
  
  // fallback: 人工组合（保留 reason）
  const controller = new AbortController();
  const listeners: Array<{ s: AbortSignal; fn: () => void }> = [];
  
  const attach = (s: AbortSignal) => {
    const fn = () => {
      try { 
        controller.abort((s as any).reason ?? new DOMException('Aborted', 'AbortError')); 
      } catch {}
      // 移除所有监听，避免泄露
      listeners.forEach(({ s, fn }) => s.removeEventListener('abort', fn));
    };
    s.addEventListener('abort', fn, { once: true });
    listeners.push({ s, fn });
  };
  
  list.forEach(attach);
  return controller.signal;
}

/**
 * 创建带超时的 AbortSignal，优先使用原生 timeout
 */
export function createTimeoutSignal(ms: number): AbortSignal | undefined {
  const timeoutFn = (AbortSignal as any).timeout as ((ms: number) => AbortSignal) | undefined;
  if (typeof timeoutFn === 'function') return timeoutFn(ms);
  
  const controller = new AbortController();
  setTimeout(() => {
    try { 
      controller.abort(new DOMException('TimeoutError', 'AbortError')); 
    } catch {}
  }, ms);
  return controller.signal;
}

/**
 * 简单信号量实现
 * 用于控制并发执行的工具数量
 */
export class Semaphore {
  private permits: number;
  private waitQueue: Array<() => void> = [];

  constructor(permits: number) {
    this.permits = permits;
  }

  async acquire(): Promise<void> {
    if (this.permits > 0) {
      this.permits--;
      return;
    }
    
    return new Promise<void>((resolve) => {
      this.waitQueue.push(resolve);
    });
  }

  release(): void {
    if (this.waitQueue.length > 0) {
      const waiter = this.waitQueue.shift()!;
      waiter();
    } else {
      this.permits++;
    }
  }
}

/**
 * 生成缓存键
 */
export function generateCacheKey(toolId: string, parameters: Record<string, any>): string {
  return `${toolId}:${stableStringify(parameters)}`;
}

/**
 * 规范化路径
 * 统一处理Windows和Unix路径格式
 */
export function normalizePath(path: string, workspaceRoot: string = ''): string {
  if (!path || typeof path !== 'string') return path;
  
  const isAbsWin = /^[a-zA-Z]:[\\\/]/.test(path) || path.startsWith('\\\\');
  const isAbsPosix = path.startsWith('/');
  const sep = (workspaceRoot && (workspaceRoot.includes('\\') || /^[a-zA-Z]:\\|^\\\\/.test(workspaceRoot))) ? '\\' : '/';
  
  if (isAbsWin || isAbsPosix) {
    // 绝对路径：尽量转换为与工作区一致的分隔符风格
    return workspaceRoot ? path.replace(/[\\\/]/g, sep) : path;
  } else if (workspaceRoot) {
    // 相对路径：基于工作区根目录
    const rel = path.replace(/[\\\/]/g, sep);
    return workspaceRoot.endsWith(sep) ? (workspaceRoot + rel) : (workspaceRoot + sep + rel);
  } else {
    return path;
  }
}

/**
 * 错误分类器
 * 将各种错误分类为标准类型
 */
export function classifyError(error: any): { type: string; message: string } {
  const errorMessage = String(error?.message || error);
  
  if (error?.name === 'AbortError' || /abort/i.test(errorMessage)) {
    if (/timeout/i.test(errorMessage)) {
      return { type: 'timeout', message: 'Operation timed out' };
    } else {
      return { type: 'aborted', message: 'Operation was aborted' };
    }
  } else if (/not found|no such file/i.test(errorMessage)) {
    return { type: 'not_found', message: 'Resource not found' };
  } else if (/permission|access denied/i.test(errorMessage)) {
    return { type: 'permission_denied', message: 'Permission denied' };
  } else if (/too large|size/i.test(errorMessage)) {
    return { type: 'resource_too_large', message: 'Resource too large' };
  } else {
    return { type: 'unknown', message: errorMessage };
  }
}

/**
 * 验证工具调用格式
 */
export function validateToolCall(toolCall: any): boolean {
  const func = toolCall?.function;
  return func && func.name && typeof func.name === 'string' && func.name.trim();
}

/**
 * 生成唯一ID
 */
export function generateId(prefix: string = 'id'): string {
  return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}